home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / AMIWBENC.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  13KB  |  535 lines

  1. /*    SCCS Id: @(#)amiwbench.c - Amiga Workbench interface  3.0   */
  2. /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1990      */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6.  
  7. #undef TRUE
  8. #undef FALSE
  9. #undef COUNT
  10. #undef NULL
  11.  
  12. #ifdef LATTICE
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <proto/icon.h>
  16. #endif
  17.  
  18. #include <workbench/startup.h>
  19. #include <workbench/workbench.h>
  20. #include <exec/memory.h>
  21. #include <ctype.h>
  22.  
  23. #ifdef LATTICE
  24. #include <string.h>
  25. #undef strlen            /* grrr */
  26. #endif
  27.  
  28. #define ALLOC_SIZE        ((long)sizeof(struct FileInfoBlock))
  29.  
  30. #ifdef AZTEC_C
  31. /*
  32.  * Change when manx becomes ANSI complient
  33.  */
  34. BPTR FDECL(CurrentDir,(BPTR));
  35. BPTR FDECL(ParentDir, (BPTR));
  36. BPTR FDECL(Lock, (char *, long));
  37. void *FDECL(AllocMem, (long, long));
  38. void FDECL(FreeMem, (void *, long));
  39. unsigned short FDECL(Examine, (BPTR, struct FileInfoBlock *));
  40. struct Library *FDECL(OpenLibrary,(char *, long));
  41. struct DiskObject *FDECL(GetDiskObject, (char *));
  42.  
  43. extern struct Library *IconBase;
  44. #endif
  45.  
  46. #ifdef AMIGA_WBENCH
  47. static void FDECL(ami_wb_findme,(char *,char *,struct WBArg *));
  48. static int FDECL(buildPath,(LONG,struct FileInfoBlock *,char *));
  49. static void FDECL(insert,(char *,char *));
  50.  
  51. BOOL FromWBench=0;        /* if FALSE, this file is a big NOP */
  52. static BOOL FromTool=0;        /* or from Project (ergo nothing to restore) */
  53. static char argline[80];    /* fake command line from ToolTypes */
  54. static BOOL TTparse=0;        /* parsing tooltypes? */
  55. static BOOL KillIcon=FALSE;    /* delayed expunge of user's icon */
  56. static char iconname[PATHLEN+5];
  57. static char origicon[PATHLEN+5];
  58. static char savefname[PL_NSIZ];        /* name from name of save file */
  59.  
  60. extern const char *classes;    /* liberated from pcmain */
  61. extern char *PATH;
  62.  
  63. /* Called after NetHack.cnf (and maybe NETHACKOPTIONS) are read.
  64.  * If this is a request to show the score file, do it here and quit.
  65.  */
  66. void ami_wbench_init(argc,argv)
  67. int argc;
  68. char *argv[];
  69. {
  70.     struct WBStartup *wbs=(struct WBStartup *)argv;
  71.     struct WBArg *wa;
  72.     int    ia;            /* arg of active icon */
  73.     int    x,doscore=0;
  74.     char     *p,*lp;
  75.     BPTR    olddir;            /* starting directory */
  76.     struct DiskObject *dobj;
  77.     char    *scorearg;
  78.     char    tmp_ramdisk[PATHLEN];
  79.     char    tmp_levels[PATHLEN];
  80.  
  81.     FromWBench=(argc==0);
  82.     if(!FromWBench)return;            /* nothing if from CLI */
  83.  
  84.     /*
  85.      * "NULL" out arrays
  86.      */
  87.     tmp_ramdisk[0] = '\0';
  88.     tmp_levels[0]  = '\0';
  89.  
  90.     IconBase=OpenLibrary("icon.library",33L);
  91.     if(!IconBase)error("icon.library missing!");
  92.  
  93.     wa=wbs->sm_ArgList;
  94.     if(wbs->sm_NumArgs>2)error("You can only play one game at a time!");
  95.     ia=wbs->sm_NumArgs-1;
  96.     strcpy(savefname,wa[ia].wa_Name);
  97.     if(!strncmp(index(savefname,'.'),".sav",4)){
  98.         *index(savefname,'.')='\0';
  99.     } else {
  100.         savefname[0]='\0';    /* don't override if not save file */
  101.     }
  102.  
  103.     olddir=CurrentDir(wa[ia].wa_Lock);   /* where the icon is */
  104.  
  105.     dobj=GetDiskObject(wa[ia].wa_Name);
  106.     (void)CurrentDir(olddir);        /* and back */
  107.     if(!dobj){
  108.         error("Sorry, I can't find your icon!");
  109.     }
  110.  
  111.     FromTool=(dobj->do_Type==WBTOOL)?1:
  112.             (dobj->do_Type==WBPROJECT)?0:
  113.             (error("Sorry, I don't recognize this icon type!"),1);
  114.  
  115.     ami_wb_findme(SAVEF,SAVEP,&wa[ia]);
  116.     strcpy(origicon,SAVEF);
  117.     strcat(origicon,".info");
  118.  
  119.     argline[0]='\0';
  120.     if(dobj->do_ToolTypes)for(x=0;p=dobj->do_ToolTypes[x];x++){
  121.         lp=index(p,'=');
  122.         if(!lp++){
  123.             if((strncmp(p,"SCORES",6)==0) ||
  124.                (strncmp(p,"SCORE",5)==0)){
  125.                 doscore=1;
  126.                 scorearg=malloc(strlen(p)+1);
  127.                 strcpy(scorearg,p);
  128.             } else {
  129.                 TTparse=TRUE;
  130.                 parseoptions(p,(boolean)TRUE);
  131.                 TTparse=FALSE;
  132.             }
  133.         } else {
  134.             while(*lp && isspace(*lp))lp++;
  135.                 /* vars and lengths below match amidos.c,
  136.                  * but there is no SAVE - you put the
  137.                  * icon where you want it, and GRAPHICS
  138.                  * just doesn't belong        */
  139.             if(!strncmp(p,"OPTIONS",4)){
  140.                 TTparse=TRUE;
  141.                 parseoptions(lp,(boolean)TRUE);
  142.                 TTparse=FALSE;
  143.             } else
  144.             if(lp[0]=='#'){
  145.                 /* for perversity's sake, a comment */
  146.             } else
  147.             if(!strncmp(p,"HACKDIR",4)){
  148.                 strncpy(hackdir,lp,PATHLEN);
  149.             } else
  150.             if(!strncmp(p,"RAMDISK",3)){
  151.                 strncpy(tmp_ramdisk,lp,PATHLEN);
  152.             } else
  153.             if(!strncmp(p,"LEVELS",4)){
  154.                 strncpy(tmp_levels,lp,PATHLEN);
  155.             } else
  156.             if(!strncmp(p,"PATH",4)){
  157.                 strncpy(PATH,lp,PATHLEN);
  158.             } else
  159.                 /* new things */
  160.             if((strncmp(p,"CMDLINE",7)==0)||
  161.                (strncmp(p,"COMMANDLINE",11)==0)){
  162.                 strncpy(argline,lp,79);
  163.             } else
  164.             {
  165.                 msmsg("Bad ToolTypes line: '%s'\n",p);
  166.                 getreturn("to continue");
  167.             }
  168.         }
  169.     }
  170.         /* cleanup - from amidos.c, except we only change things
  171.          * that are explicitly changed, since we already
  172.          * did this once to get the defaults (in amidos.c)    */
  173.     if(plname[0])plnamesuffix();    /* from amidos.c */
  174.     if(tmp_levels[0])strcpy(permbones,tmp_levels);
  175.     if(tmp_ramdisk[0]){
  176.         strcpy(levels,tmp_ramdisk);
  177.         strcpy(bones,levels);
  178.         if(strcmp(permbones,levels))
  179.             ramdisk=TRUE;
  180.     } else {
  181.         if(tmp_levels[0]){
  182.             strcpy(levels,tmp_levels);
  183.             strcpy(bones,levels);
  184.         }
  185.     }
  186.  
  187.     FreeDiskObject(dobj);    /* we'll get it again later if we need it */
  188.  
  189.     if(doscore){
  190.         long ac;
  191.         char *p;
  192.         char **av=calloc(1,50*sizeof(char *));
  193. #ifdef CHDIR
  194.         chdirx(hackdir,0);
  195. #endif
  196.         av[0]="NetHack";            /* why not? */
  197.         for(ac=1,p=scorearg;*p;ac++){
  198.             av[ac]=p;
  199.             while(*p && !isspace(*p))p++;
  200.             if(!*p)break;
  201.             *p++='\0';
  202.             while(*p && isspace(*p))p++;
  203.             if(ac==1)sprintf(av[ac],"-s");    /* overwrite SCORES */
  204.         }
  205.         prscore(ac+1,av);
  206.         exit(0);        /* overloaded */
  207.     }
  208.  
  209.             /* if the user started us from the tool icon,
  210.              * we can't save the game in the same place
  211.              * we started from, so pick up the plname
  212.              * and hope for the best.
  213.              */
  214.     if(FromTool){
  215.         strcat(SAVEF,plname);
  216.         strcat(SAVEP,plname);
  217.     }
  218. }
  219.  
  220. /* Simulate the command line (-s is already done, although this is
  221.  * not exactly the way it should be). Note that we only handle flags
  222.  * that are not otherwise available in NetHack.cnf        */
  223. void ami_wbench_args(){
  224.     char *p=argline;
  225.     if(!FromWBench)return;
  226.     if(!argline)return;
  227.  
  228.     while(*p){
  229.         switch(*p++){
  230.         case '-':    break;
  231. #ifdef NEWS
  232.         case 'n':    flags.nonews = TRUE;
  233. #endif
  234. #if defined(WIZARD) || defined(EXPLORE_MODE)
  235. # ifndef EXPLORE_MODE
  236.         case 'X':
  237. # endif
  238.         case 'D':
  239. # ifdef WIZARD
  240. #  ifdef KR1ED
  241.             if(!strcmp(plname,WIZARD_NAME)){
  242. #  else
  243.             if(!strcmp(plname,WIZARD)){
  244. #  endif
  245.                 wizard=TRUE;break;
  246.             }
  247.             /* else fall through */
  248. # endif
  249. # ifdef EXPLORE_MODE
  250.         case 'X':    discover=TRUE;
  251. # endif
  252.                 break;
  253. #endif
  254. #ifdef DGK
  255.         case 'r':    /* no ram disk */
  256.             ramdisk=FALSE;
  257.             break;
  258. #endif
  259.         default:
  260.             p--;
  261.             if(index(classes,toupper(*p))){
  262.                 char *t=pl_character;
  263.                 int cnt=sizeof(pl_character)-1;
  264.                 while(cnt && *p && !isspace(*p))*t++=*p++,cnt--;
  265.                 *t=0;
  266.             } else {
  267.                 Printf("Unknown switch: %s\n",p);
  268.                 return;
  269.             }
  270.         }
  271.     }
  272. }
  273.  
  274.  
  275. /* IF (from workbench) && (currently parsing ToolTypes)
  276.  * THEN print error message and return 0
  277.  * ELSE return 1
  278.  */
  279. ami_wbench_badopt(oopsline)
  280. char *oopsline;
  281. {
  282.     if(!FromWBench)return 1;
  283.     if(!TTparse)return 1;
  284.     Printf("Bad Syntax in OPTIONS in ToolTypes: %s.",oopsline);
  285.     return 0;
  286. }
  287.  
  288. /* Construct (if necessary) and fill in icon for given save file */
  289. void ami_wbench_iconwrite(base)
  290. char *base;
  291. {
  292.     BPTR lock;
  293.     char tmp[PATHLEN+5];
  294.  
  295.     if(!FromWBench)return;
  296.  
  297.     strcpy(tmp,base);
  298.     strcat(tmp,".info");
  299.     if(FromTool){                /* user clicked on main icon */
  300.         (void)CopyFile(DEFAULT_ICON,tmp);
  301.     } else {                /* from project */
  302.         lock=Lock(tmp,ACCESS_READ);
  303.         if(lock==0){    /* maybe our name changed - try to get
  304.                  * original icon */
  305.             if(!Rename(origicon,tmp)){
  306.                 /* nope, build a new icon */
  307.             lock=Lock(DEFAULT_ICON,ACCESS_READ);
  308.             if(lock==0)return;        /* no icon today */
  309.             UnLock(lock);
  310.             (void)CopyFile(DEFAULT_ICON,tmp);
  311.             }
  312.         } else UnLock(lock);
  313.     }
  314.     KillIcon=FALSE;
  315.  
  316. /*    dobj=GetDiskObject(base);
  317.     anything we need to change?  I don't think so.
  318.     PutDiskObject(base,dobj);
  319.     FreeDiskObject(dobj);
  320. */
  321. }
  322.  
  323. /* How much disk space will we need for the icon? */
  324. int ami_wbench_iconsize(base)
  325. char *base;
  326. {
  327.     struct FileInfoBlock *fib;
  328.     BPTR lock;
  329.     int    rv;
  330.     char tmp[PATHLEN+5];
  331.  
  332.     if(!FromWBench)return(0);
  333.     strcpy(tmp,base);
  334.     strcat(tmp,".info");
  335.     lock=Lock(tmp,ACCESS_READ);
  336.     if(lock==0){    /* check the default */
  337.         lock=Lock(DEFAULT_ICON,ACCESS_READ);
  338.         if(lock==0)return(0);
  339.     }
  340.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
  341.     if(!Examine(lock,fib)){
  342.         UnLock(lock);
  343.         FreeMem(fib, ALLOC_SIZE);
  344.         return(0);            /* if no icon, there
  345.                          * never will be one */
  346.     }
  347.     rv=fib->fib_Size+strlen(plname);    /* guessing */
  348.     UnLock(lock);
  349.     FreeMem(fib, ALLOC_SIZE);
  350.     return(rv);
  351. }
  352.  
  353. /* Delete the icon associated with the given file (NOT the file itself! */
  354. /* (Don't worry if the icon doesn't exist */
  355. void ami_wbench_unlink(base)
  356. char *base;
  357. {
  358.     if(!FromWBench)return;
  359.  
  360.     strcpy(iconname,base);
  361.     strcat(iconname,".info");
  362.     KillIcon=TRUE;            /* don't do it now - this way the user
  363.                      * gets back whatever picture we had
  364.                      * when we started if the game is
  365.                      * saved again             */
  366. /*    unlink(tmp); */
  367. }
  368.  
  369. /* Check for a saved game.
  370. IF not a saved game -> -1
  371. IF can't open SAVEF -> -1
  372. ELSE -> fd for reading SAVEF */
  373. int ami_wbench_getsave(mode)
  374. int mode;
  375. {
  376.     BPTR lock;
  377.     struct FileInfoBlock *fib;
  378.  
  379.     if(!FromWBench)return(open(SAVEF,mode));
  380.             /* if the file will be created anyway, skip the
  381.              * checks and just do it            */
  382.     if(mode & O_CREAT)return(open(SAVEF,mode));
  383.     if(FromTool)return(-1);        /* otherwise, by definition, there
  384.                      * isn't a save file (even if a
  385.                      * file of the right name exists) */
  386.     if(savefname[0])
  387.         strncpy(plname,savefname,PL_NSIZ-1); /* restore poly'd name */
  388.     lock=Lock(SAVEF,ACCESS_READ);
  389.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE, MEMF_CLEAR);
  390.     if(lock && Examine(lock,fib)){
  391.         if(fib->fib_Size>100){    /* random number << save file size */
  392.             UnLock(lock);
  393.                         FreeMem(fib,ALLOC_SIZE);
  394.             return(open(SAVEF,mode));
  395.         } else {
  396.                 /* this is a dummy file we need because
  397.                  * workbench won't duplicate an icon with no
  398.                  * "real" data attached - try to get rid of it.
  399.                  */
  400.             UnLock(lock);
  401.             unlink(SAVEF);
  402.             FreeMem(fib,ALLOC_SIZE);
  403.             return(-1);
  404.         }
  405.     }
  406.     FreeMem(fib,ALLOC_SIZE);
  407.     return(-1);        /* give up */
  408. }
  409.  
  410. #ifdef notdef
  411. /* cleanup */
  412. void ami_wbench_cleanup(){
  413.     if(!FromWBench)return;
  414.     if(KillIcon){
  415.         unlink(iconname);
  416.     } else {
  417.         if(!FromTool){    /* game started and ended in one session */
  418.             char buf[PATHLEN+5];
  419.             strcpy(buf,SAVEF);
  420.             strcat(buf,".info");
  421.             unlink(buf);
  422.         }
  423.     }
  424. }
  425. #endif
  426.  
  427. /* get printable version of where we came from */
  428. static void ami_wb_findme(bufp,dirp,wa)
  429.     char *bufp,*dirp;
  430.     struct WBArg *wa;
  431.     {
  432.     BPTR dir;
  433.     struct FileInfoBlock *fib;
  434.     char *p;
  435.     int len;
  436.  
  437.     dir=wa->wa_Lock;
  438.  
  439.     fib = (struct FileInfoBlock *)AllocMem(ALLOC_SIZE,MEMF_CLEAR);
  440.     buildPath(dir,fib,dirp);
  441.     strcat(dirp,"/");
  442.     strcpy(bufp,dirp);
  443.     if(FromTool){
  444.         /* do nothing - filename will be added later */
  445.     } else {
  446.         strcat(bufp,wa->wa_Name);
  447.     };
  448.     /* I know this looks redundent, but its not since we may add
  449.      * a slash after returning from buildPath
  450.      */
  451.     p=index(bufp,':');
  452.     if(!p){
  453.         p=index(bufp,'/');
  454.         if(p)*p=':';
  455.     }
  456.     p=index(dirp,':');
  457.     if(!p){
  458.         p=index(dirp,'/');
  459.         if(p)*p=':';
  460.     }
  461.     /* We found the icon - but we need the main file. */
  462.     len=strlen(bufp);
  463.     if(len<5)return;            /* who knows? */
  464.     if(strcmp(".info",&bufp[len-5]))return; /* who knows? */
  465.     bufp[len-5]='\0';
  466.         FreeMem(fib, ALLOC_SIZE);
  467. }
  468.  
  469. /* Carolyn Scheppner - CATS, AmigaMail II-34 */
  470. static int
  471. buildPath(inlock,fib,buf)
  472. LONG inlock;
  473. struct FileInfoBlock *fib;           /* ASSUMED LONGWORD BOUNDARY!! */
  474. char *buf;
  475.     {
  476.     int i;
  477.     LONG lock,oldlock;
  478.     BOOL MyOldLock = FALSE;
  479.  
  480.     buf[0]='\0';
  481.     lock=inlock;
  482.  
  483.     while(lock){
  484.         if(Examine(lock,fib)){
  485.             if(fib->fib_FileName[0]>' '){
  486.                 if(buf[0])insert(buf,"/");
  487.                 insert(buf,fib->fib_FileName);
  488.             }
  489.         }
  490.         oldlock=lock;
  491.         lock=ParentDir(lock);
  492.         if(MyOldLock) UnLock(oldlock);
  493.         else MyOldLock=TRUE;
  494.     }
  495.     if(fib->fib_FileName[0]>' '){
  496.         for(i=0;i<(strlen(buf));i++){
  497.             if(buf[i]=='/'){
  498.                 buf[i]=':';
  499.                 break;
  500.             }
  501.         }
  502.     }
  503.     else insert(buf,"RAM:");
  504.     return((int)strlen(buf));
  505. }
  506. static void
  507. insert(buf,s)
  508. char *buf,*s;
  509. {
  510.     char tmp[256];
  511.     strcpy(tmp,buf);
  512.     strcpy(buf,s);
  513.     strcpy(&buf[strlen(s)],tmp);
  514. }
  515.  
  516. #if 0 /* CopyFile should be OK */
  517. static void copyicon(from,to)
  518. char *from,*to;
  519. {
  520.     int df,dt;
  521.     char buf[512];
  522.     int len=512;
  523.  
  524.     df=open(from,O_RDONLY);
  525.     dt=open(to,O_WRONLY,0);
  526.     while(len=512){
  527.         len=read(df,buf,len);
  528.         write(dt,buf,len);
  529.     }
  530.     close(df);
  531.     close(dt);
  532. }
  533. #endif
  534. #endif /* AMIGA_WBENCH */
  535.